# -*- coding:utf-8 -*-

"""
    批量上传zip包到７牛云，然后更新数据到服务器
    * zip包命名格式：    V05S74,V1SHZ1_1.23_2.01_20160525.zip
        SN号前6位代表不同设备类型（多个使用逗号连接）_待升级版本_此包版本_升级包打包时间.zip
    Usage:    python upload_files.py <filename | filepath>

    七牛账号：
        huangtao@idealsee.cn
        huangtao
"""

import os, sys, json, random, hashlib
import urllib, requests
# from requests.adapters import HTTPAdapter

import qiniu.config
from fileinput import filename

import logging

DOWNLOAD_URL    = 'http://fota.idealens.com/media01/'
SERVER_URL      = 'http://52.8.24.239:32001'
# SERVER_URL      = 'http://localhost:8080'
USERNAME        = 'idealsee'
PASSWORD        = 'idealsee2012'


def get_zip_files(file_path):
    """ 获取当前需要上传的zip包文件名
    """
    file_names = []
    for parent, dirnames, filenames in os.walk(file_path):
        for filename in filenames:
            if filename.endswith('.zip'):
                if check_filename(filename):
                    file_names.append(os.path.join(parent, filename))
    return file_names


def check_filename(filename):
    """ 校验文件名格式是否正确
    """
    l = filename[:-4].split('_')
    if len(l) != 4 or '' in l:
        print '\tERROR zip file name:', filename
        return False
    return True


def check_file_exists(filename):
    """ 校验文件是否已经在服务端存在
    """
    md5, _ = get_file_md5(filename)
    file_name = filename.split(os.path.sep)[-1]

    conn = requests.session()

    # conn.proxies = {'http': 'http://10.0.1.37:3128',
    #                'https': 'http://10.0.1.37:3128'}

    # 先登陆
    uri = '/login/?'
    params = {
        'username':   USERNAME,
        'password':   PASSWORD
    }
    url = SERVER_URL + uri + urllib.urlencode(params)
    r = conn.post(url)
    d = json.loads(r.content)
    if d['code'] != 0:
        return False, 'login error!'

    # 检查是佛存在
    uri = '/file/check_exits/?'
    params = {
        'md5':      md5,
        'filename': file_name
    }
    url = SERVER_URL + uri + urllib.urlencode(params)
    r = conn.get(url)
    d = json.loads(r.content)
    if d['code'] != 0:
        return False
    else:
        return True

def update_file_2_server(filename):
    logging.error(filename)
    """ 更新已经上传到７牛云的文件到服务端
    """
    if not os.path.isfile(filename):
        return False, 'file not exists!'
    
    conn = requests.session()

    # conn.proxies = {'http': 'http://10.0.1.37:3128',
    #                'https': 'http://10.0.1.37:3128'}
    
    # 先登陆
    uri = '/login/?'
    params = {
        'username':   USERNAME,
        'password':   PASSWORD
    }
    url = SERVER_URL + uri + urllib.urlencode(params)
    r = conn.post(url)
    d = json.loads(r.content)
    if d['code'] != 0:
        return False, 'login error!'
    
    # 上传更新文件数据
    md5, size = get_file_md5(filename)
    file_name = filename.split(os.path.sep)[-1]
    logging.error(filename)
    # download_url = random.choice(DOWNLOAD_URLS) + file_name
    file_ext = filename.split(".")[-1]
    download_url = DOWNLOAD_URL + md5 + "-full." + file_ext
    
    
    json_file = filename[:-3] + 'json'
    if not os.path.isfile(json_file):
        return False, 'json file not exists!'
    
    with open(json_file, 'r') as f:
        d = json.load(f, encoding='utf8')
        change_logs = '\n'.join(d['change_logs'])
        finger_point = d['finger_point']


    logging.error("before upload")

    uri = '/file/upload'
    # headers = {'Content-Type': 'multipart/form-data'}

    datas = {
              'filename':       file_name,
              'size':           size,
              'md5':            md5,
              'change_logs':    change_logs,
              'finger_point':   finger_point,
              'download_url':   download_url,
              }
    files = {
        'file' :  open(file_name, 'rb') 
    }
    url = SERVER_URL + uri
    r = conn.post(url, data = datas, files = files)
    logging.error(r)
    try:
        d = json.loads(r.content)
        if d['code'] != 0:
            return False, d['info']
    except Exception, e:
        pass
    return True, 'update success!'


def get_file_md5(filename):
    """ 分片计算文件的md5
    """
    block_size = 1024 * 1024 * 5    # 5M分片计算
    m = hashlib.md5()
    size = 0
    with open(filename, 'rb') as f:
        while True:
            data = f.read(block_size)
            if not data:
                break
            m.update(data)
            size += len(data)
    return m.hexdigest().lower(), size


def main():
    if len(sys.argv) != 2:
        print '\n Usage:    python ', __file__, ' <filename | filepath>\n'
        exit(0)
    path = os.path.abspath(sys.argv[1])
    if os.path.isdir(path):
        filenames = get_zip_files(path) # 上传path路径下所有zip文件
    else:
        filenames = [path]              #　上传单个文件
    
    ERRORS = []
    print '\n\tUpload Files:\n'
    for index, filename in enumerate(filenames):
        print ''.join(['\t', str(index + 1), '. ', filename])

        if not check_file_exists(filename):
            ERRORS.append(filename)
            ERRORS.append('file already exists!')
            continue

        # ret, info = upload_files_2_qiniu(filename)
        # if not ret:
        #     ERRORS.append(filename)
        #     ERRORS.append(info)
        #     continue

        ret, info = update_file_2_server(filename)
        if not ret:
            ERRORS.append(filename)
            ERRORS.append(info)

    if len(ERRORS):
        print '\n\t', '*' * 100
        print '\n\tUpload Failed:\n'
        index = 1
        while ERRORS:
            print ''.join(['\t', str(index), '. ', ERRORS[0]])
            print '\t   result: ', ERRORS[1], '\n'
            index += 1
            ERRORS = ERRORS[2:]


if __name__ == '__main__':
    main()
